﻿using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace LeakView.common
{
    public interface AnyConfig
    {
        Any get(string key);
    }

    public class AnyConfigs
    {
        private static string _default_filename = Environment.CurrentDirectory + "\\app.ini";

        public static IniAnyConfig get(string section)
        {
            return IniAnyConfig.build(@_default_filename, section);
        }

        public static IniAnyConfig get(string section, string prefix)
        {
            return IniAnyConfig.build(@_default_filename, section, prefix);
        }
    }

    public class IniAnyConfig : AnyConfig
    {
        // 返回0表示失败，非0为成功  
        [DllImport("kernel32", CharSet = CharSet.Auto)]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        // 返回取得字符串缓冲区的长度  
        [DllImport("kernel32", CharSet = CharSet.Auto)]
        private static extern long GetPrivateProfileString(string section, string key, string strDefault, StringBuilder retVal, int size, string filePath);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        private static extern int GetPrivateProfileInt(string section, string key, int nDefault, string filePath);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);

        public static IniAnyConfig build(string filename, string section, string prefix)
        {
            IniAnyConfig config = new IniAnyConfig
            {
                filename = filename,
                section = section,
                prefix = prefix
            };
            return config;
        }

        public static IniAnyConfig build(string filename, string section)
        {
            return build(filename, section, null);
        }

        private string filename = null;
        public string Filename { get => filename; set => filename = value; }

        private string section = null;
        public string Section { get => section; set => section = value; }

        private string prefix = null;
        public string Prefix { get => prefix; set => prefix = value; }


        public Any get(string key)
        {
            StringBuilder vRetSb = new StringBuilder(2048);
            GetPrivateProfileString(Section, Key(key), "", vRetSb, 2048, Filename);
            var str = vRetSb.ToString();
            return Anys<string>.At(str.Count() == 0 ? null : str);
        }

        public bool set(string key, string value)
        {
            return 0 != WritePrivateProfileString(Section, Key(key), value, Filename);
        }

        private string Key(string key)
        {
            if (Prefix != null)
            {
                return Prefix + "_" + key;
            }
            else
            {
                return key;
            }
        }

    }
}
